// Copyright 2017 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the “License”); you may not use this file except in
// compliance with the License.  You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
/////////////////////////////////////////////////////////
// includes
/////////////////////////////////////////////////////////
#include "mlDotp.h"
#include "math_fns.h"
#include "bar.h"
#include "utils.h"
#include "bench.h"

/////////////////////////////////////////////////////////
// shared globals
/////////////////////////////////////////////////////////

  __attribute__ ((section(".heapsram")))  static const float fv0[400] = { 79.8909073F, 42.770153F, 37.3707581F,
    86.5761261F, 36.3307457F, 58.1311111F, 21.5260906F, 74.1878357F, 85.407341F,
    87.4643402F, 36.7720642F, 51.3365822F, 86.0471573F, 73.0734406F, 3.00337839F,
    71.3564072F, 28.5184689F, 49.051033F, 80.6565323F, 95.0634766F, 4.85815382F,
    12.6612043F, 3.32408166F, 93.9623108F, 30.2548828F, 25.1607666F, 20.6386776F,
    85.5178833F, 96.2566299F, 96.483078F, 16.5808296F, 46.0287476F, 31.477232F,
    82.0829468F, 76.4301605F, 76.45578F, 95.3278046F, 26.6075211F, 89.0537109F,
    68.653717F, 13.1467609F, 58.5743F, 26.027401F, 20.4478302F, 26.5001545F,
    45.509594F, 84.9637451F, 21.0066795F, 80.3692627F, 65.4361877F, 21.9340019F,
    74.5703659F, 19.576643F, 8.96823883F, 2.86525559F, 81.6841202F, 42.3759232F,
    66.6821594F, 50.6373405F, 26.7430096F, 10.8249731F, 22.9552708F, 33.6464615F,
    70.0219727F, 6.65047884F, 44.330513F, 29.2295914F, 52.2248383F, 60.9073372F,
    39.8711586F, 72.7837143F, 8.14774799F, 89.050354F, 74.923851F, 72.4592285F,
    84.5162659F, 0.652195F, 26.1397114F, 42.365F, 58.5078697F, 71.9659F,
    16.7082253F, 3.64289618F, 21.2201595F, 34.4965935F, 33.2536697F, 37.6869049F,
    47.0485916F, 97.3561325F, 67.9392929F, 54.2027779F, 79.7240829F, 50.9949455F,
    46.1667F, 72.0194168F, 79.962944F, 43.7122536F, 3.80286527F, 47.5935173F,
    92.3882599F, 17.6686802F, 58.9308586F, 53.7754555F, 45.5250511F, 40.7248802F,
    89.9909F, 2.30624413F, 31.9250202F, 37.8995781F, 25.7034779F, 72.4331589F,
    45.0915146F, 36.2661896F, 4.40866232F, 53.5184097F, 95.9409485F, 91.9751816F,
    98.9183044F, 59.1322823F, 57.5476837F, 54.0432777F, 64.9625626F, 80.7637939F,
    1.93156922F, 21.4000988F, 67.0574722F, 94.4202271F, 62.1284523F, 74.4208F,
    19.9119854F, 69.7681198F, 38.8599358F, 65.0809555F, 43.3430672F, 72.6865616F,
    91.4300308F, 55.3415222F, 60.588089F, 3.18345523F, 83.2944641F, 7.83060932F,
    68.1132889F, 26.0874348F, 13.3933954F, 4.04654789F, 6.55583811F, 27.8182621F,
    49.9442406F, 18.1963367F, 22.6706505F, 72.7276688F, 27.6175117F, 82.7316208F,
    43.2075615F, 29.9563675F, 69.246994F, 55.3798943F, 61.9056053F, 43.8625336F,
    98.2482605F, 2.11767387F, 74.2889328F, 29.6332073F, 64.3483047F, 9.12910652F,
    90.0976868F, 82.155304F, 10.2452946F, 73.084053F, 99.4416F, 53.2195549F,
    74.806633F, 21.1869316F, 72.2430954F, 60.7919312F, 65.2267914F, 10.8272257F,
    48.1520386F, 88.0878525F, 95.2254105F, 38.5528336F, 87.8191223F, 94.7608109F,
    21.3401318F, 28.8353424F, 63.3119507F, 7.68615913F, 15.5757446F, 63.8250313F,
    57.5533829F, 46.7063484F, 36.1738853F, 83.1345291F, 22.721035F, 87.5674591F,
    18.791153F, 8.01122856F, 36.9004364F, 32.2833862F, 80.188652F, 19.1160812F,
    26.6115456F, 98.5424728F, 29.0419388F, 8.42162514F, 64.9345169F, 52.6385422F,
    34.1583061F, 35.6798172F, 4.48986816F, 48.1640892F, 74.35923F, 20.806469F,
    83.8579254F, 54.6678047F, 42.4924049F, 39.4960518F, 13.1985626F, 80.1075058F,
    49.0474091F, 86.216423F, 27.949379F, 28.0767021F, 78.8714676F, 2.23246193F,
    20.8751202F, 73.110466F, 57.0637245F, 92.3691101F, 47.1171951F, 94.4011307F,
    39.9574852F, 34.430748F, 7.07936382F, 85.8422546F, 10.9659195F, 40.1643448F,
    82.1541367F, 56.3713837F, 66.2926712F, 58.9806175F, 25.3099461F, 61.9072952F,
    26.7557812F, 25.4381447F, 31.4834709F, 11.4360704F, 78.0829773F, 32.8768806F,
    49.5024681F, 39.719F, 73.1642F, 70.9428864F, 16.4224892F, 56.7064F,
    45.4083862F, 5.06786919F, 28.2894611F, 89.086853F, 75.8604584F, 62.7495956F,
    35.4356613F, 83.9615631F, 86.3167419F, 89.2571945F, 37.3490715F, 41.9019852F,
    67.1237946F, 43.7569847F, 41.9630508F, 13.6435881F, 69.6412888F, 58.0666847F,
    68.7831039F, 95.3805161F, 78.9546051F, 82.2352219F, 95.9601669F, 62.9794312F,
    35.7719383F, 1.99965084F, 80.8023148F, 9.51388454F, 74.8143539F, 4.56834936F,
    18.9668198F, 51.3195343F, 56.8069763F, 18.7810459F, 31.4976978F, 58.6061401F,
    29.173378F, 80.4453888F, 95.9045105F, 53.6682281F, 20.7738495F, 27.884779F,
    21.482481F, 50.9788628F, 39.5769081F, 94.8635635F, 61.1134644F, 61.12043F,
    48.1017876F, 66.7041855F, 69.2172775F, 27.0378189F, 24.2358227F, 48.9019356F,
    61.1947937F, 81.2341766F, 78.1505432F, 20.0619297F, 19.852829F, 39.523365F,
    61.0666771F, 43.8278656F, 93.9011765F, 46.2468262F, 19.0360107F, 4.00059271F,
    28.8780098F, 71.7255F, 61.9200478F, 88.257843F, 89.313324F, 0.670004606F,
    35.4970589F, 1.67695212F, 86.2602463F, 7.65273094F, 54.4366951F, 7.90204763F,
    20.8213654F, 55.2351646F, 83.4602737F, 89.2445068F, 10.8639956F, 71.3848724F,
    99.7810059F, 67.8846893F, 50.783947F, 43.8522148F, 88.4760666F, 44.8978386F,
    37.9134674F, 96.7935486F, 6.40804291F, 35.9275093F, 9.1124649F, 40.1618462F,
    33.0604362F, 1.48161972F, 8.41872597F, 35.6345177F, 91.6911774F, 26.4733124F,
    87.2930679F, 30.6008873F, 6.08370972F, 93.6233902F, 89.7554092F, 78.6719513F,
    47.0157471F, 43.1284447F, 70.2321777F, 98.6818695F, 92.0987473F, 20.6835899F,
    20.3334942F, 8.37097263F, 9.0257206F, 37.5058F, 18.8195457F, 34.7356377F,
    61.8358116F, 91.9273682F, 24.0483761F, 64.234993F, 68.9506073F, 78.2034836F,
    66.5949326F, 14.2499571F, 12.2837305F, 15.8462172F, 35.8283234F, 31.9537144F,
    91.8392792F, 83.4804459F, 98.2046204F, 77.3019104F, 67.1437149F, 5.28447F,
    47.7811203F, 49.4013443F, 12.8391333F, 50.5524864F, 94.4122238F, 21.6866951F,
    50.5531883F };

  __attribute__ ((section(".heapsram"))) static const float fv1[400] = { 10.4797945F, 21.4428463F, 34.9927597F,
    4.48862F, 68.3616333F, 90.60392F, 76.5976181F, 72.9932175F, 71.1281509F,
    17.3357391F, 57.3137817F, 69.519989F, 99.1919632F, 55.0130501F, 4.25152922F,
    20.9346657F, 37.2589035F, 87.5370941F, 91.4440079F, 77.7355194F, 97.1593933F,
    46.8521614F, 1.00149167F, 96.1604462F, 82.4172897F, 77.557F, 90.3241425F,
    54.8188629F, 52.8111801F, 89.3791656F, 50.5551796F, 42.2380257F, 40.5029793F,
    1.67812419F, 48.8038673F, 69.345047F, 13.8626184F, 22.6698914F, 97.452713F,
    71.9534912F, 14.6181631F, 31.8499489F, 15.9577246F, 9.58875275F, 14.9227571F,
    45.0245323F, 13.3350754F, 4.22489452F, 3.19060087F, 64.8169632F, 39.8030396F,
    73.5526657F, 45.4880104F, 74.4299545F, 90.9747F, 63.9740944F, 63.8820534F,
    44.3385315F, 69.4114151F, 12.6230726F, 3.94325709F, 77.1813507F, 51.3681641F,
    80.1557541F, 66.6605225F, 37.6462669F, 83.4632645F, 44.8592644F, 61.9045296F,
    15.5725403F, 59.4005966F, 3.34734368F, 91.3054F, 74.425148F, 81.912262F,
    92.8159256F, 88.5696945F, 28.8597374F, 74.9369659F, 55.6794F, 21.0497265F,
    16.8834763F, 98.8988953F, 86.4233475F, 71.0768585F, 19.5838985F, 36.3974533F,
    36.0491714F, 97.5162888F, 23.9760799F, 85.8617783F, 48.5235786F, 11.6023073F,
    95.843132F, 4.64661407F, 19.4300671F, 44.3167381F, 5.26092815F, 80.2540359F,
    21.9098892F, 4.86771154F, 63.2003899F, 38.9698296F, 66.3448715F, 73.1353531F,
    19.719698F, 34.5689278F, 40.001976F, 55.9489365F, 41.469429F, 48.0479927F,
    23.1164322F, 51.4186134F, 61.3380356F, 59.2878265F, 42.1601601F, 1.2039125F,
    63.2324562F, 76.920372F, 81.4870224F, 72.0760727F, 90.2679672F, 27.2428322F,
    88.5470123F, 16.9151936F, 80.7213745F, 80.4802475F, 30.6918354F, 63.4711342F,
    90.1784515F, 89.5688553F, 98.276741F, 85.103241F, 26.8828316F, 36.3612671F,
    52.8875237F, 41.1141701F, 81.8041611F, 55.7440147F, 23.8634491F, 10.9064922F,
    50.6961517F, 10.2906694F, 24.8903427F, 63.1228447F, 76.1898575F, 51.1606789F,
    64.4145813F, 63.5908852F, 90.158371F, 8.42251301F, 11.7062922F, 63.280098F,
    20.7354126F, 95.8753586F, 81.7719F, 25.9047604F, 74.5343933F, 80.956459F,
    74.5343704F, 49.7473755F, 99.5705795F, 1.50430477F, 1.0683006F, 24.2634201F,
    17.727396F, 6.99008F, 94.5474701F, 74.4183197F, 76.7375717F, 30.5424175F,
    40.841198F, 46.8883F, 36.0368767F, 58.3756065F, 46.4538765F, 31.1084194F,
    89.9641342F, 2.4611187F, 36.1071663F, 45.0636253F, 86.5955124F, 79.8311081F,
    48.5275192F, 89.8169098F, 62.4748154F, 43.0556335F, 35.5112686F, 29.4042568F,
    5.76643133F, 28.9492245F, 91.7149887F, 77.8894424F, 11.383316F, 36.6441917F,
    70.7772751F, 21.157196F, 59.6544075F, 56.0684624F, 50.3628159F, 39.2795219F,
    4.62581968F, 57.4432831F, 53.5718117F, 73.1208725F, 90.4186249F, 78.7109222F,
    9.69924259F, 84.3485413F, 19.4323788F, 53.7297F, 64.1333237F, 88.9440155F,
    83.9347763F, 93.425827F, 64.7929382F, 50.4463882F, 51.5433693F, 84.1764145F,
    64.9124069F, 44.1327667F, 30.9222431F, 47.6325188F, 2.08004069F, 9.45461273F,
    98.6888351F, 59.8644409F, 61.3189583F, 69.6885071F, 71.554924F, 7.57580233F,
    0.149923265F, 26.3931F, 16.0078621F, 8.27295113F, 63.028347F, 38.7778702F,
    66.1891327F, 15.7253313F, 39.5959549F, 75.251358F, 47.0433922F, 70.0023117F,
    93.4319534F, 79.0952225F, 42.7127876F, 17.2781162F, 64.1713562F, 21.9616146F,
    50.9413033F, 65.3045197F, 44.6929932F, 52.2010078F, 59.4291801F, 94.6725616F,
    40.6119194F, 1.68274391F, 54.8624039F, 34.0559654F, 71.5954666F, 42.7070808F,
    7.76367712F, 32.4318466F, 83.6709595F, 98.3154144F, 29.7649498F, 17.0019016F,
    70.6627121F, 56.0998573F, 35.1129532F, 85.9942627F, 1.083251F, 78.5767441F,
    87.0722427F, 0.224369735F, 48.7579803F, 36.1720314F, 5.84084845F,
    15.0025301F, 50.6292648F, 45.1829872F, 24.284338F, 13.7164F, 1.46490705F,
    21.665617F, 88.6411057F, 32.5631409F, 55.5788193F, 45.1800079F, 85.2784195F,
    42.170681F, 59.5754509F, 79.5285339F, 78.8007507F, 83.4320374F, 49.3011703F,
    20.8897018F, 59.706295F, 67.3278046F, 28.3800831F, 94.2425156F, 80.9229736F,
    4.12231684F, 56.6837082F, 0.670556068F, 71.629837F, 15.4572449F, 79.8435287F,
    84.6728287F, 13.8016615F, 35.9647751F, 34.3534317F, 91.247963F, 93.6513214F,
    6.16246319F, 9.76277542F, 8.53743362F, 62.4129028F, 71.6358337F, 5.43115854F,
    94.4407F, 79.0584183F, 65.0573196F, 22.348299F, 58.5857735F, 81.2369537F,
    55.0923576F, 84.584137F, 42.2387085F, 89.5718384F, 11.1286774F, 32.7562485F,
    18.489399F, 46.9108925F, 85.6685181F, 73.3561401F, 61.3893242F, 14.4354219F,
    49.6790543F, 0.813811839F, 76.076767F, 99.5085831F, 75.611557F, 54.6094093F,
    84.991684F, 40.8285294F, 33.0893402F, 79.1704F, 49.5233192F, 12.987957F,
    80.5707855F, 88.057869F, 60.492794F, 40.5633316F, 23.1110859F, 35.6966362F,
    92.7494888F, 65.1788F, 32.7010536F, 84.9069595F, 21.5657463F, 22.5313206F,
    35.9678917F, 27.2272205F, 26.8303146F, 10.9348497F, 68.0769882F, 17.7919827F,
    56.2273407F, 59.08535F, 78.6359787F, 65.2571869F, 53.1470261F, 12.5945206F,
    83.1829681F, 40.1703911F, 7.50963783F, 2.77413177F, 57.4499817F, 59.4368591F,
    93.5397797F, 26.0786858F, 93.633194F, 10.6351156F, 20.1271114F, 63.8240318F,
    14.850646F, 81.2141953F, 67.6006775F, 94.1587753F, 70.8025055F, 4.89266539F,
    88.1162186F, 90.9852676F, 12.5988655F, 63.9574432F, 52.5050354F, 79.3574905F,
    60.9531097F, 27.9867287F };

  __attribute__ ((section(".heapsram"))) static const float fv2[8] = { 267084.906F, 267079.594F, 259512.312F,
    259507.125F, 247154.188F, 247149.25F, 252832.156F, 252827.094F };

/////////////////////////////////////////////////////////
// subfunctions
/////////////////////////////////////////////////////////


/////////////////////////////////////////////////////////
// main testing function 
/////////////////////////////////////////////////////////
int main(int argc, const char * const argv[])
{
  (void)argc;
  (void)argv;

  int coreid;
  int it;

  boolean_T pass;
  float f0;
  volatile float tmp;
  int i0;
  
  /////////////////////////////////////////////////////////
  // main test loop 
  // each core loops over a kernel instance
  /////////////////////////////////////////////////////////

  coreid = get_core_id();

  printf("starting %d kernel iterations... (coreid = %d)\n",KERNEL_ITS,coreid);

  synch_barrier();
  
  if (coreid>3)
    coreid=coreid-4;

  perf_begin();
  
  for(it = 0; it < getKernelIts(); it++)
  {
    // matlab kernel
    f0 = 0.0F;
    for (i0 = 0; i0 < 100; i0++) {
      f0 += fv1[i0 + 100 * coreid] * fv0[i0 + 100 * coreid];
    }
    tmp = f0;
  }

  synch_barrier();

  perf_end();

  /////////////////////////////////////////////////////////
  // check results
  /////////////////////////////////////////////////////////

  pass = (f0 <= fv2[0 + (coreid << 1)]) && (f0 >= fv2[1 + (coreid << 1)]);
  printErrors(!pass, 0, f0 ,fv2[0 + (coreid << 1)] ,fv2[1 + (coreid << 1)]);

  flagPassFail(pass, get_core_id());
  
/////////////////////////////////////////////////////////
// synchronize and exit
/////////////////////////////////////////////////////////

  return !pass;
}

